/** 
 *  缩略图实现，将图片(jpg、bmp、png、gif等等)真实的变成想要的大小 
 */ 
package com.htzos.common.util;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;  
import java.awt.Rectangle;
import java.awt.Transparency;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;  
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.io.InputStream;

import javax.imageio.ImageIO;  
import javax.imageio.stream.ImageOutputStream;

import com.sun.image.codec.jpeg.JPEGCodec;  
import com.sun.image.codec.jpeg.JPEGImageEncoder;  
/******************************************************************************* 
 * 缩略图类（通用） 本java类能将jpg、bmp、png、gif图片文件，进行等比或非等比的大小转换。 具体使用方法 
 * compressPic(大图片路径,生成小图片路径,大图片文件名,生成小图片文名,生成小图片宽度,生成小图片高度,是否等比缩放(默认为true)) 
 */  
public class CompressPicUtil {
	 private File file = null; // 文件对象   
     private String inputDir; // 输入图路径  
     private String outputDir; // 输出图路径  
     private String inputFileName; // 输入图文件名  
     private String outputFileName; // 输出图文件名  
     private int outputWidth = 100; // 默认输出图片宽  
     private int outputHeight = 100; // 默认输出图片高  
     private boolean proportion = true; // 是否等比缩放标记(默认为等比缩放)  
     public CompressPicUtil() { // 初始化变量  
         inputDir = "";   
         outputDir = "";   
         inputFileName = "";   
         outputFileName = "";   
         outputWidth = 100;   
         outputHeight = 100;   
     }   
     public void setInputDir(String inputDir) {   
         this.inputDir = inputDir;   
     }   
     public void setOutputDir(String outputDir) {   
         this.outputDir = outputDir;   
     }   
     public void setInputFileName(String inputFileName) {   
         this.inputFileName = inputFileName;  
     }   
     public void setOutputFileName(String outputFileName) {   
         this.outputFileName = outputFileName;   
     }   
     public void setOutputWidth(int outputWidth) {  
         this.outputWidth = outputWidth;   
     }   
     public void setOutputHeight(int outputHeight) {   
         this.outputHeight = outputHeight;   
     }   
     public void setWidthAndHeight(int width, int height) {   
         this.outputWidth = width;  
         this.outputHeight = height;   
     }   
     /**
      * 图片旋转
      * @param src 图片文件
      * @param angel	旋转角度
      * @return
      */
     public static BufferedImage Rotate(Image src, int angel) {  
         int src_width = src.getWidth(null);  
         int src_height = src.getHeight(null);  
         // calculate the new image size  
         Rectangle rect_des = CalcRotatedSize(new Rectangle(new Dimension(  
                 src_width, src_height)), angel);  
   
         BufferedImage res = null;  
         res = new BufferedImage(rect_des.width, rect_des.height,  
                 BufferedImage.TYPE_INT_RGB);  
         Graphics2D g2 = res.createGraphics();  
         // transform  
         g2.translate((rect_des.width - src_width) / 2,  
                 (rect_des.height - src_height) / 2);  
         g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);  
   
         g2.drawImage(src, null, null);  
         return res;  
     }  
   
     public static Rectangle CalcRotatedSize(Rectangle src, int angel) {  
         // if angel is greater than 90 degree, we need to do some conversion  
         if (angel >= 90) {  
             if(angel / 90 % 2 == 1){  
                 int temp = src.height;  
                 src.height = src.width;  
                 src.width = temp;  
             }  
             angel = angel % 90;  
         }  
   
         double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;  
         double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;  
         double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;  
         double angel_dalta_width = Math.atan((double) src.height / src.width);  
         double angel_dalta_height = Math.atan((double) src.width / src.height);  
   
         int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha  
                 - angel_dalta_width));  
         int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha  
                 - angel_dalta_height));  
         int des_width = src.width + len_dalta_width * 2;  
         int des_height = src.height + len_dalta_height * 2;  
         return new java.awt.Rectangle(new Dimension(des_width, des_height));  
     } 
     
     public static InputStream rotateImg(BufferedImage image, int degree, Color bgcolor) throws IOException {

 		int iw = image.getWidth();//原始图象的宽度 
 		int ih = image.getHeight();//原始图象的高度
 		int w = 0;
 		int h = 0;
 		int x = 0;
 		int y = 0;
 		degree = degree % 360;
 		if (degree < 0)
 			degree = 360 + degree;//将角度转换到0-360度之间
 		double ang = Math.toRadians(degree);//将角度转为弧度

		if (degree == 180 || degree == 0 || degree == 360) {
			w = iw;
			h = ih;
		} else if (degree == 90 || degree == 270) {
			w = ih;
			h = iw;
		} else {
			// int d = iw + ih;
			double cosVal = Math.abs(Math.cos(ang));
			double sinVal = Math.abs(Math.sin(ang));
			w = (int) (sinVal * ih) + (int) (cosVal * iw);
			h = (int) (sinVal * iw) + (int) (cosVal * ih);
		}

 		x = (w / 2) - (iw / 2);//确定原点坐标
 		y = (h / 2) - (ih / 2);
 		BufferedImage rotatedImage = new BufferedImage(w, h, image.getType());
 		Graphics2D gs = (Graphics2D)rotatedImage.getGraphics();
 		if(bgcolor==null){
 			rotatedImage  = gs.getDeviceConfiguration().createCompatibleImage(w, h, Transparency.TRANSLUCENT);
 		}else{
 			gs.setColor(bgcolor);
 			gs.fillRect(0, 0, w, h);//以给定颜色绘制旋转后图片的背景
 		}
 		
 		AffineTransform at = new AffineTransform();
 		at.rotate(ang, w / 2, h / 2);//旋转图象
 		at.translate(x, y);
 		AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_BICUBIC);
 		op.filter(image, rotatedImage);
 		image = rotatedImage;
 		
 		ByteArrayOutputStream  byteOut= new ByteArrayOutputStream();
 		ImageOutputStream iamgeOut = ImageIO.createImageOutputStream(byteOut);
 		
 		ImageIO.write(image, "jpg", iamgeOut);
 		InputStream  inputStream = new ByteArrayInputStream(byteOut.toByteArray());
 		return inputStream;
 	}
     /*  
      * 获得图片大小  
      * 传入参数 String path ：图片路径  
      */   
     public long getPicSize(String path) {   
         file = new File(path);   
         return file.length();   
     }  
       
     // 图片处理   
     public String compressPic() {   
         try {   
             //获得源文件   
             file = new File(inputDir + inputFileName);   
             if (!file.exists()) {   
                 return "";   
             }   
             Image img = ImageIO.read(file);   
             // 判断图片格式是否正确   
             int newWidth = 0; 
             int newHeight = 0;   
             if (img.getWidth(null) == -1) {  
                 System.out.println(" can't read,retry!" + "<BR>");   
                 return "no";   
             } else {   
                 // 判断是否是等比缩放   
                 if (this.proportion == true) {   
                     // 为等比缩放计算输出的图片宽度及高度   
                     double rate1 = ((double) img.getWidth(null)) / (double) outputWidth + 0.1;   
                     double rate2 = ((double) img.getHeight(null)) / (double) outputHeight + 0.1;   
                     // 根据缩放比率大的进行缩放控制   
                     double rate = rate1 > rate2 ? rate1 : rate2;   
                     newWidth = (int) (((double) img.getWidth(null)) / rate);   
                     newHeight = (int) (((double) img.getHeight(null)) / rate);   
                 } else {   
                	 //长宽定值缩放
                     double heightImageType = (double) img.getHeight(null);
                     double widthImageType = (double) img.getWidth(null);
                     if(widthImageType>heightImageType&&widthImageType>outputWidth){
                    	 newWidth=outputWidth;
                    	 newHeight=(int) ((heightImageType*outputWidth)/widthImageType);
                     }else if(widthImageType<heightImageType&&heightImageType>outputHeight){
                    	 newHeight=outputHeight;
                    	 newWidth=(int) ((outputHeight*widthImageType)/heightImageType);
                     }else{
                    	 newWidth = (int)widthImageType;
                    	 newHeight = (int)heightImageType;
                     }
                 }   
                 BufferedImage tag = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);   
                 
                /* 
                 * Image.SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 
                 * 优先级比速度高 生成的图片质量比较好 但速度慢 
                 */   
                tag.getGraphics().drawImage(img.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH), 0, 0, null);  
                FileOutputStream out = new FileOutputStream(outputDir + outputFileName);  
                // JPEGImageEncoder可适用于其他图片类型的转换   
                JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);   
                encoder.encode(tag);   
                out.close();   
             }   
         } catch (IOException ex) {   
             ex.printStackTrace();   
         }   
         return "ok";   
    }   
    public String compressPic (String inputDir, String outputDir, String inputFileName, String outputFileName) {   
        // 输入图路径   
        this.inputDir = inputDir;   
        // 输出图路径   
        this.outputDir = outputDir;   
        // 输入图文件名   
        this.inputFileName = inputFileName;   
        // 输出图文件名  
        this.outputFileName = outputFileName;   
        return compressPic();   
    }   
    public String compressPic(String inputDir, String outputDir, String inputFileName, String outputFileName, int width, int height, boolean gp) {   
        // 输入图路径   
        this.inputDir = inputDir;   
        // 输出图路径   
        this.outputDir = outputDir;   
        // 输入图文件名   
        this.inputFileName = inputFileName;   
        // 输出图文件名   
        this.outputFileName = outputFileName;   
        // 设置图片长宽  
        setWidthAndHeight(width, height);   
        // 是否是等比缩放 标记   
        this.proportion = gp;   
        return compressPic();   
    }   
     
    // main测试   
    // compressPic(大图片路径,生成小图片路径,大图片文件名,生成小图片文名,生成小图片宽度,生成小图片高度,是否等比缩放(默认为true))  
    public static void main(String[] arg) {   
//    	CompressPicUtil mypic = new CompressPicUtil();   
//        System.out.println("输入的图片大小：" + mypic.getPicSize("e:\\1.jpg")/1024 + "KB");   
//        int count = 0; // 记录全部图片压缩所用时间  
//        for (int i = 0; i < 100; i++) {   
//            int start = (int) System.currentTimeMillis();   // 开始时间   
//            mypic.compressPic("e:\\", "e:\\test\\", "1.jpg", "r1"+i+".jpg", 120, 120, true);   
//            int end = (int) System.currentTimeMillis(); // 结束时间   
//            int re = end-start; // 但图片生成处理时间   
//            count += re; System.out.println("第" + (i+1) + "张图片压缩处理使用了: " + re + "毫秒");   
//            System.out.println("输出的图片大小：" + mypic.getPicSize("e:\\test\\r1"+i+".jpg")/1024 + "KB");   
//        }  
//        System.out.println("总共用了：" + count + "毫秒");   
    	
    }   
}
